/*
 * File: translator.c
 * Brief: 翻译器，实现恒强上机文件的转换
 *
 * Change Log:
 * Date         Author      Note
 * 2014.05.16   Herbert     create
 * 2014.05.21   Herbert     增加V领转换,及PAT转DAT功能
 * 2014.05.22   Herbert     将simulator改为translator,simulator只实现了模拟纱嘴位置的功能
 *                          translator功能更全面，将文件转换工作全部实现
 * 2014.05.23   Herbert     增加函数translator_get_color_range
 * 2014.05.24   Herbert     增加参数type,可以读取dat文件和pat文件，因为后缀名是一样的，所以用type区分
 * 2014.06.13   Herbert     修改恒强摇床的转换，恒强的超过1针，超过1/2针在102字节
 * 2014.06.18   Herbert     修改translator_get_dat_end函数，修改end的值，左行从0改为-1，右行从width-1改为width，
 *                          否则会造成最后一个点或者第一个点遍历不到
 * 2014.06.20   Herbert     增加translator_get_color函数，获取指定点的色码
 * 2014.07.09   Herbert     translator_get_yinta_range函数增加pcolormask参数，被屏蔽掉的色码不扫描
 * 2014.07.10   Herbert     增加是否全选的判断
 * 2014.08.21   Herbert     增加遍历con文件，获取执行到指定行纱嘴停放点功能
 * 2014.09.02   Herbert     增加遍历线圈位置的功能
 * 2015.06.25   wzwz        矫正右边续片纱嘴号
 */
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <malloc.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <mh/common.h>
#include <mh/com.h>
#include <mh/sram.h>
#include "knit.h"
#include "translator.h"

enum {YARN_NONE = 0, YARN_IN = 1, YARN_OUT = 2};
#define MH_FILE_SYNC()               sync()


/*
 *
 */
static void cnt2con_act(uchar *des, uchar *src)
{
    if(src[2] == 0x01)
    {
        if(src[12] == 0x01)
        {
            des[2] = 0x06;
            des[12] = 0x06;
            des[7] |= des[13];
            des[8] |= des[14];
            des[17] |= des[3];
            des[18] |= des[4];
        }
        else if(src[12] == 0x08)
        {
            des[2] = 0x01;
            des[12] = 0x07;
            des[17] |= des[3];
            des[18] |= des[4];
        }
        else if(src[12] == 0)
        {
            des[2] = 0x01;
            des[12] = 0x04;
            des[17] |= des[3];
            des[18] |= des[4];
        }
    }
    else if(src[2] == 0x08)
    {
        if(src[12] == 0x01)
        {
            des[2] = 0x07;
            des[12] = 0x01;
            des[7] |= des[13];
            des[8] |= des[14];
        }
        else if(src[12] == 0x0E)
        {
            des[2] = 0x08;
            des[12] = 0x0C;
        }
        else
        {
            des[2] = src[2];
            des[12] = src[12];
        }
    }
    else if(src[2] == 0)
    {
        if(src[12] == 0x01)
        {
            des[2] = 0x04;
            des[12] = 0x01;
            des[7] |= des[13];
            des[8] |= des[14];
        }
        else if(src[12] == 0x0E)
        {
            des[2] = 0;
            des[12] = 0x0C;
        }
        else
        {
            des[2] = 0;
            des[12] = src[12];
        }
    }
    else if(src[2] == 0x0E)
    {
        if(src[12] == 0x0E)
        {
            des[2] = 0x0C;
            des[12] = 0x0C;
        }
        else
        {
            des[2] = 0x0C;
            des[12] = src[12];
        }
    }
    else
    {
        if(src[12] == 0x0E)
        {
            des[12] = 0x0C;
        }
        else
        {
            des[12] = src[12];
        }
        des[2] = src[2];
    }
    des[6] = des[2];
    des[16] = des[12];
}
/*
 *
 */
static void line_cnt2con(int dir, uchar *des, uchar *src)
{
    //act
    int i = 0;
#if (MH_SYS_CAM == 1)
    if (dir % 2)
    {
        memcpy (des, &src[20], 40);
        cnt2con_act (des, &src[20]);
    }
    else
    {
        memcpy (des, src, 40);
        cnt2con_act (des, src);
    }
#else
    memcpy(des, src, 40);
    for (i = 0; i < 8; i++)
    {
        des[5 + 10 * i] = 0;
        des[9 + 10 * i] = 0;
    }
    cnt2con_act(des, src);
    cnt2con_act(&des[20], &src[20]);
#endif
    //40-79
    //yarn

#if (MH_SYS_CAM == 1)
    for(i = 0; i < 8; i++)
    {
        int pos = (dir % 2) ? 84 : 81;
        int n = ((src[pos] >> (7 - i)) & 1) << i;
        des[81] |= n;
    }
#else
    for(i = 0; i < 8; i++)
    {
        int n = ((src[81] >> (7 - i)) & 1) << i;
        des[81] |= n;

        n = ((src[84] >> (7 - i)) & 1) << i;
        des[84] |= n;

        des[87] |= ((src[87] >> (7 - i)) & 1) << i;
        des[90] |= ((src[90] >> (7 - i)) & 1) << i;
    }
#endif //yarn out

    if((src[81] & src[82]) && (des[82] == 0))
    {
        des[82] = FLAG_YARN_OUT;
    }


    if((src[84] & src[82]) && des[85] == 0)
    {
        des[85] = FLAG_YARN_OUT;
    }

    //dumu 1
    des[92] = src[92];
    if (des[92] > 32)
    {
        des[92] = 32;
    }
    //sudu
    des[93] = src[93];
    //labu
    des[94] = src[94];
    //fulabu
    des[95] = src[95] & 0x7F;
    //kaihe
    des[96] = src[96] & 0x7F;
    //zhankai
    des[97] = src[97];
    //program
    des[98] = src[98];
    //99
    //rock 1
    des[100] = src[100] & 0xF0;
    if((src[100] & 0x0F) == 1)
    {
        des[100] |= 1;
    }
    else if((src[100] & 0x0F) == 2)
    {
        des[100] |= 2;
    }
    //rock 2
    des[101] = src[101];
    //恒强的超过1针，超过1/2针在102字节
    if (src[102] == 1)
    {
        if ((des[100] & 0xF0) == 0x80 ||
            (des[100] & 0xF0) == 0xC0)
        {
            des[100] += 0x20;
        }
    }
    else if (src[102] == 2)
    {
        if ((des[100] & 0xF0) == 0x80 ||
            (des[100] & 0xF0) == 0xC0)
        {
            des[100] += 0x10;
        }
    }
    //dumu 2
    des[102] = src[125];
    if (des[102] > 32)
    {
        des[102] = 32;
    }
    //103 104
    //夹子闭
    //恒强对应关系
    //0b01010101
    //   4 3 2 1
    des[105] = src[85] & 0x01;
    des[105] |= (src[85] >> 1) & 0x02;
    des[105] |= (src[85] >> 2) & 0x04;
    des[105] |= (src[85] >> 3) & 0x08;

    //夹子开
    //恒强对应关系
    //0b10101010
    //   4 3 2 1
    des[106] = (src[85] >> 1) & 0x01;
    des[106] |= (src[85] >> 2) & 0x02;
    des[106] |= (src[85] >> 3) & 0x04;
    des[106] |= (src[85] >> 4) & 0x08;
    //yarn stop
    des[107] = src[107];
    //ret len
    des[108] = src[108];
    //109
    //scissor恒强有4把剪刀,1-2为左剪刀,3-4为右剪刀
    if(src[99] & 0x03)
    {
        des[110] = 1;
    }
    else if(src[99] & 0x0C)
    {
        des[110] = 2;
    }
    else
    {
        des[110] = 0;
    }
    //des[110] = src[99] & 1 ? 1 : src[99] & 2 ? 2 : src[99] & 4 ? 3 : src[99] & 8 ? 4 : 0;
    //111-115
    //112
    des[112] = des[95];
    //116-118
    des[116] = src[116];
    //dumubuzheng
    int k1f = 0;
    if(des[2] != 0x01 && des[2] != 0x04 && des[2] != 0x06 && des[2] != 0)
    {
        k1f = 1;
    }
    int k1b = 0;
    if(des[12] != 0x01 && des[12] != 0x04 && des[12] != 0x06 && des[12] != 0)
    {
        k1b = 1;
    }
    int k2f = 0;
    if(des[22] != 0x01 && des[22] != 0x04 && des[22] != 0x06 && des[22] != 0)
    {
        k2f = 1;
    }
    int k2b = 0;
    if(des[32] != 0x01 && des[32] != 0x04 && des[32] != 0x06 && des[32] != 0)
    {
        k2b = 1;
    }
    if(k2b + k2f + k1b + k1f > 2)
    {
        des[119] = 4;
    }
    else if(k2b + k2f == 2)
    {
        des[119] = 2;
    }
    else if(k1b + k1f == 2)
    {
        des[119] = 2;
    }
    else if(k1b + k1f == 1 && k2b + k2f == 1)
    {
        des[119] = 3;
    }
    else
    {
        des[119] = 1;
    }
    //des[119] = src[91];
    //sink
    des[120] = src[127];
    //jieyue
    short n = (src[118] << 8) | src[117];
    ++n;
    des[122] = n & 0xFF;
    des[123] = (n >> 8) & 0xFF;
    //124-125
    //num
    des[126] = src[119];
    //引塔夏
    if (src[113] & 0x7F)
    {
        des[121] = 0x80;
    }
    //写入新版本标志
    des[MHFCRS_NEW_FLAG_BYTE] = MHFCRS_NEW_FLAG;
}
/*
 *
 */
int translator_reverse (int gauze)
{
    int new_gauze = 0;
    int i = 0;

    for (i = 0; i < 16; i++)
    {
        if (gauze & (0x01 << i))
        {
            new_gauze |= 0x01 << (GAUZE_NUM - 1 - i);
        }
    }

    return new_gauze;
}
/** \brief  :获取色码范围
 *
 * \param   :[in]translator-转换器
 *           [in]prow-当前处理的这一行的花样高度,0-前床;1-后床
 *           [in]pcolor-色码，0-前床；1-后床
 *           [out]start_pos-起点
 *           [out]end_pos-终点
 * \return  :none
 * \date    :2014\05\23
 */
void translator_get_color_range (uchar *pat_buf,
                                 int width,
                                 int height,
                                 int *prow,
                                 int *pcolor,
                                 int *start_pos,
                                 int *end_pos)
{
    assert (prow != NULL);
    assert (pcolor != NULL);
    assert (start_pos != NULL);
    assert (end_pos != NULL);

    int w;
    int j = 0;
    int h = 0;
    uchar color = 0;

    *start_pos = -1;
    *end_pos = -1;

    if ((pcolor[0] == 0) && (pcolor[1] == 0))
    {
        return;
    }

    //find start pos
    for (w = 0; w < width; w++)
    {
        for (j = 0; j < 2; j++)
        {
            h = prow[j];
            if (h > 0 && h < height)
            {
                color = pat_buf[(h - 1) * width + w];

                if ((0x01 << color) & pcolor[j])
                {
                    *start_pos = w;
                    break;
                }
            }
        }

        if (*start_pos >= 0)
        {
            break;
        }
    }

    if (*start_pos < 0)
    {
        return;
    }

    //find end pos
    for (w = width - 1; w >= 0; w--)
    {
        for (j = 0; j < 2; j++)
        {
            h = prow[j];
            if (h > 0 && h < height)
            {
                color = pat_buf[(h - 1) * width + w];

                if ((0x01 << color) & pcolor[j])
                {
                    *end_pos = w;
                    break;
                }
            }
        }

        if (*end_pos >= 0)
        {
            break;
        }
    }
}
/** \brief  :获取引塔夏各个段的范围
 *
 * \param   :[in]translator-转换器
 *           [in]prow-当前处理的这一行的花样高度,0-前床;1-后床
 *           [out]start_pos-每个段的起点
 *           [out]end_pos-每个段的终点
 *           [in]pcolormask-色码掩码，只扫描没被屏蔽掉的色码，为空则不屏蔽
 * \return  :色码段的个数
 * \date    :2014\05\21
 */
int translator_get_yinta_range (uchar *pat_buf,
                                int width,
                                int height,
                                int *prow,
                                int *start_pos,
                                int *end_pos,
                                int *pcolormask)
{
    int w;
    int n = 0;
    int i = 0;
    int h = (prow[0] > 0) ? prow[0] : prow[1];

    if (h < 1 || h > height)
    {
        return 0;
    }

    for (w = 0; w < width; w++)
    {
        uchar color = pat_buf[(h - 1) * width + w];

        if (pcolormask != NULL)
        {
            if (((0x01 << color) & *pcolormask) == 0)
            {
                color = 0;
            }
        }

        if((start_pos[n] < 0) && (color != 0))
        {
            start_pos[n] = w;
        }

        if((color == 0) || (w == width - 1))
        {
            if(start_pos[n] >= 0)
            {
                //由于偷吃所以判断连续10个0为分界点
                int t = 0;
                for(t = 1; t < 10; t++)
                {
                    if(w + t < width)
                    {
                        uchar c = pat_buf[(h - 1) * width + w + t];
                        if (pcolormask != NULL)
                        {
                            if (((0x01 << c) & *pcolormask) == 0)
                            {
                                c = 0;
                            }
                        }

                        if(c)
                        {
                            break;
                        }
                        continue;
                    }
                    t = 10;
                    break;
                }

                if(t > 9)
                {
                    end_pos[n] = w - 1;
                    if (w == width - 1)
                    {
                        end_pos[n] = width - 1;
                    }
                    n++;
                }
            }
        }

        if(n > GAUZE_NUM - 1)
        {
            break;
        }
    }

    /**< 用F填充0号色 */
    for (i = 0; i < n; i++)
    {
        for (w = start_pos[i]; w <= end_pos[i]; w++)
        {
            uchar color = pat_buf[(h - 1) * width + w];
            if (color == 0)
            {
                pat_buf[(h - 1) * width + w] = 0x0F;
            }
        }
    }

    return n;
}
/*
 * @translator:
 * @mrow: machine row
 * @prow: pat row, 0-front, 1-back
 * @pcolor: pat color, 0-front, 1-back
 * @type: 0-色码起点；１－色码终点
 * NOTE: rightward, return end point
 *       leftward, return start point
 */
int translator_get_dat_end (uchar *pat_buf, int width, int height,
        int mrow, int *prow, int *pcolor, int type)
{
    int start = 0;
    int end = width;
    int delta = 1;
    int pos = -1;
    uchar *fpat_base = NULL;
    uchar *bpat_base = NULL;
    int w = 0;

    //rightward, find the end point
    //leftward, find the start point
    if (mrow % 2)
    {
        delta = -1;
        start = width - 1;
        end = -1;
    }

    //find start point
    if (type == 0)
    {
        if (mrow % 2)
        {
            delta = 1;
            start = 0;
            end = width;
        }
        else
        {
            delta = -1;
            start = width - 1;
            end = -1;
        }

    }

    pos = -1;
    fpat_base = NULL;
    if ((prow[0] > 0) && (prow[0] <= height))
    {
        fpat_base = pat_buf + (prow[0] - 1)* width;
    }

    bpat_base = NULL;
    if ((prow[1] > 0) && (prow[1] <= height))
    {
        bpat_base = pat_buf + (prow[1] - 1) * width;
    }

    if ((fpat_base == NULL) && (bpat_base == NULL))
    {
        return -1;
    }

    w = start;
    while (w != end)
    {
        if (fpat_base != NULL)
        {
            if ((0x01 << fpat_base[w]) & pcolor[0])
            {
                pos = w;
                break;
            }
        }

        if (bpat_base != NULL)
        {
            if ((0x01 << bpat_base[w]) & pcolor[1])
            {
                pos = w;
                break;
            }
        }

        w += delta;
    }

    return pos;
}
/** \brief  :更新引塔夏纱嘴的位置
 *
 * \param   :[in]translator
 *           [in]mrow-machine row
 *           [in]gauze-当前行纱嘴
 *           [in]in-纱嘴带入标志,bit0-bit7-->1-8号纱嘴
 *           [out]new_gauze-生成的新纱嘴
 *           [in]start_pos-色码段的起点
 *           [in]end_pos-色码段的终点
 *           [in]section-色码段个数
 * \return  :none
 * \date    :2014\05\21
 * \author  :herbert
 */
void translator_update_yinta_gauze_pos (TRANSLATOR *translator,
                                        int mrow,
                                        int gauze,
                                        int in,
                                        int *new_gauze,
                                        int *start_pos,
                                        int *end_pos,
                                        int section)
{
    assert (translator != NULL);
    assert (new_gauze != NULL);
    assert (start_pos != NULL);
    assert (end_pos != NULL);

    int i, j, n;
    int des = 0;
    int m = 0;
    int find = FALSE;
    n = 0;

    if (mrow % 2)        /**< 从小到大排列 */
    {
        for (i = 0; i < section; i++)
        {
            find = FALSE;
            for (j = 0; j < 8; j++)
            {
                if ((gauze & (0x01 << j)) == 0)
                {
                    continue;
                }

                //检测j 和 j + 8
                //同一个序号的纱嘴，恒强的格式不能识别左边的纱嘴和右边的纱嘴
                //所以要检测一下纱嘴j 和 j + 8的位置，只要能找到一个符合要求的纱嘴就OK,
                //因为同一个系统在同一段不可能带2把一样的纱嘴
                for (m = 0; m < 2; m++)
                {
                    des = j + m * 8;
                    if ((translator->gauze_pos[des] >= 0) &&
                        (translator->gauze_pos[des] <= start_pos[i]) &&
                        ((translator->gauze_dir[des] % 2) == 1))
                    {
                        if (new_gauze[n] == 0)          /**< 第一把纱嘴 */
                        {
                            new_gauze[n] = des + 1;
                        }
                        else                            /**< 第二把纱嘴 */
                        {
                            new_gauze[n] |= (des + 1) << 8;
                        }
                        /**< 设置终点 */
                        translator->gauze_pos[des] = end_pos[i];
                        translator->gauze_dir[des] = RIGHTSIDE;
                        find = TRUE;
                        break;
                    }

                }
            }

            if (find)
            {
                n++;
                continue;
            }
            for (j = 0; j < 8; j++)
            {
                if ((gauze & (0x01 << j)) == 0)
                {
                    continue;
                }

                if (in & (0x01 << j))
                {
                    if (translator->gauze_pos[j] < 0)
                    {
                        des = j;
                    }
                    else
                    {
                        des = j + 8;
                    }
                    if (new_gauze[n] == 0)          /**< 第一把纱嘴 */
                    {
                        new_gauze[n] = des + 1;
                    }
                    else                            /**< 第二把纱嘴 */
                    {
                        new_gauze[n] |= (des + 1) << 8;
                    }
                    /**< 设置终点 */
                    translator->gauze_pos[des] = end_pos[i];
                    translator->gauze_dir[des] = RIGHTSIDE;
                    find = TRUE;
                }
            }

            n++;
        }
    }
    else                /**< 从大到小排列 */
    {
        for (i = section - 1; i >= 0; i--)
        {
            find = FALSE;
            for (j = 0; j < 8; j++)
            {
                if ((gauze & (0x01 << j)) == 0)
                {
                    continue;
                }

                //检测j 和 j + 8
                //同一个序号的纱嘴，恒强的格式不能识别左边的纱嘴和右边的纱嘴
                //所以要检测一下纱嘴j 和 j + 8的位置，只要能找到一个符合要求的纱嘴就OK,
                //因为同一个系统在同一段不可能带2把一样的纱嘴
                for (m = 0; m < 2; m++)
                {
                    des = j + m * 8;
                    if ((translator->gauze_pos[des] >= 0) &&
                        (translator->gauze_pos[des] >= end_pos[i]) &&
                        ((translator->gauze_dir[des] % 2) == 0))
                    {
                        if (new_gauze[n] == 0)          /**< 第一把纱嘴 */
                        {
                            new_gauze[n] = des + 1;
                        }
                        else                            /**< 第二把纱嘴 */
                        {
                            new_gauze[n] |= (des + 1) << 8;
                        }
                        /**< 设置终点 */
                        translator->gauze_pos[des] = start_pos[i];
                        translator->gauze_dir[des] = LEFTSIDE;
                        find = TRUE;
                        break;
                    }
                }
            }

            if (find)
            {
                n++;
                continue;
            }

            for (j = 0; j < 8; j++)
            {
                if ((gauze & (0x01 << j)) == 0)
                {
                    continue;
                }

                if (in & (0x01 << j))
                {
                    if (translator->gauze_pos[j + 8] < 0)
                    {
                        des = j + 8;
                    }
                    else
                    {
                        des = j;
                    }

                    if (new_gauze[n] == 0)          /**< 第一把纱嘴 */
                    {
                        new_gauze[n] = des + 1;
                    }
                    else                            /**< 第二把纱嘴 */
                    {
                        new_gauze[n] |= (des + 1) << 8;
                    }
                    /**< 设置终点 */
                    translator->gauze_pos[des] = start_pos[i];
                    translator->gauze_dir[des] = LEFTSIDE;
                    find = TRUE;
                }
            }

            n++;
        }
    }
}
/*
 * [in]translator: translator instance
 * [in]mrow: 机器行数
 * [in]gauze: 当前执行的纱嘴
 * [in]pos: 纱嘴停放的位置
 */
int translator_update_gauze_pos (TRANSLATOR *translator, int mrow, int gauze, int pos)
{
    assert (translator != NULL);

    int i = 0;
    int new_gauze = 0;
    int des = 0;
    for (i = 0; i < 8; i++)
    {
        if (gauze & (0x01 << i))
        {
            if ((translator->gauze_dir[i] % 2) == (mrow % 2))
            {
                des = i;
                //方向一致的情况
                if (translator->gauze_dir[i + 8] == (mrow % 2))
                {
                    if (mrow % 2)
                    {
                        if (translator->gauze_pos[i + 8] >= translator->gauze_pos[i])
                        {
                            des = i + 8;
                        }
                    }
                    else
                    {
                        if (translator->gauze_pos[i + 8] <= translator->gauze_pos[i])
                        {
                            des = i + 8;
                        }
                    }
                }

                //change dir
                translator->gauze_dir[des] = 1 + translator->gauze_dir[des] % 2;
                translator->gauze_pos[des] = pos;
                new_gauze |= 0x01 << des;
            }
            else if ((translator->gauze_dir[i + 8] % 2) == (mrow % 2))
            {
                des = i + 8;
                //change dir
                translator->gauze_dir[des] = 1 + translator->gauze_dir[des] % 2;
                translator->gauze_pos[des] = pos;
                new_gauze |= 0x01 << des;
            }
            else        //第一次带纱嘴，从左边带入的定义为1-8，右边带入的定义为9-16
            {
                if (mrow % 2)       //rightward
                {
                    translator->gauze_dir[i] = RIGHTSIDE;
                    translator->gauze_pos[i] = pos;
                    new_gauze |= 0x01 << i;
                }
                else                //leftward
                {
                    translator->gauze_dir[i + 8] = LEFTSIDE;
                    translator->gauze_pos[i + 8] = pos;
                    new_gauze |= 0x01 << (i +8);
                }
            }
        }
    }

    return new_gauze;
}
/*
 * @translator:
 * @x:
 * @y:
 * NOTE:获取指定点的色码
 */
char translator_get_color (uchar *pat_buf, int width, int height, int x, int y)
{
    if (pat_buf == NULL)
    {
        return 0;
    }

    if ((x < 0 || x >= width) ||
        (y < 0 || y >= height))
    {
        return 0;
    }

    return pat_buf[y * width + x];
}
/*
 * @translator: 转换器
 * @prow: 花样行，从1开始,0-前床行数，1-后床行数
 * @pcolor: 色码,0-前床色码；1-后床色码, pcolor不包括F色码
 */
int translator_is_one_side (uchar *patbuf , int width, int height, int *prow, int *pcolor)
{
    assert (pcolor != NULL);

    int i = 0;
    int color;
    int row;
    int start = 0;
    int end = 0;
    if (patbuf == NULL)
    {
        return FALSE;
    }

    if ((pcolor[0] != 0) &&
        (pcolor[1] != 0))
    {
        return FALSE;
    }

    if (pcolor[0] != 0)
    {
        color = pcolor[0];
        row = prow[0];
    }
    else
    {
        color = pcolor[1];
        row = prow[1];
    }

    if (row <= 0 || row > height)
    {
        return FALSE;
    }

    translator_get_color_range (patbuf, width,
            height, prow, pcolor, &start, &end);
    if (start < 0 || end < 0)
    {
        return FALSE;
    }

    for (i = start; i <= end; i++)
    {
        char c = patbuf[(row - 1) * width + i];
        int filter = 0x01 << c;
        if ((filter & color) == 0)          //有不选的色码，返回FALSE
        {
            return FALSE;
        }
    }

    return TRUE;
}
/*
 * @translator: 转换器
 * @mrow: 机器行
 * @realgsp: 真正的停放点
 * @pcon_buf: 控制缓冲区
 * @gn: 纱嘴序号１－１６
 * @io: 带入带出标志,1-带入;2-带出
 * @type: 0-执行之前的位置；1-执行之后的位置
 */
static void translator_get_real_parkpos(MH_KNIT *p,
                                        int *gauze_pos,
                                        int mrow,
                                        int *realgsp,
                                        uchar *pcon_buf,
                                        int gn,
                                        int io,
                                        int type)
{
    int sp = p->start_needle - p->left_bound;
    int pp_sect = pcon_buf[107];
    int yarn = 0;
    int yarn_ext = 0;
    int i;
    int pp = 0;
    if (gn < 1 || gn > GAUZE_NUM)
    {
        return;
    }
    if(pp_sect < 1 || pp_sect > 8)
    {
        pp_sect = 1;
    }
    /* 窄纱嘴 */
    yarn = p->gauze_exchange[0][gn - 1];
    if (yarn == 0)
    {
        yarn = gn;
    }

    if (io == 2)
    {
        realgsp[yarn - 1] = gauze_pos[gn - 1] + p->yarn_out.stop[1][yarn - 1];
    }
    else if (io == 1)
    {
        realgsp[yarn - 1] = gauze_pos[gn - 1] + p->yarn_out.stop[0][yarn - 1];
    }
    else
    {
        if (mrow % 2)
        {
            pp = type ? p->yarn_stop[1][pp_sect - 1][yarn - 1] : -p->yarn_stop[0][pp_sect - 1][yarn - 1];
            realgsp[yarn - 1] = gauze_pos[gn - 1] + pp + sp;
        }
        else
        {
            pp = type ? -p->yarn_stop[0][pp_sect - 1][yarn - 1] : p->yarn_stop[1][pp_sect - 1][yarn - 1];
            realgsp[yarn - 1] = gauze_pos[gn - 1] + pp + sp;
        }
    }
    /* 宽纱嘴　*/
    yarn_ext = p->gauze_exchange[1][gn - 1];
    if(yarn_ext)
    {
        if (io == 2)
        {
            realgsp[yarn_ext - 1] = gauze_pos[gn - 1] + p->yarn_out.stop[1][yarn_ext - 1];
        }
        else if (io == 1)
        {
            realgsp[yarn_ext - 1] = gauze_pos[gn - 1] + p->yarn_out.stop[0][yarn_ext - 1];
        }
        else
        {
            if (mrow % 2)
            {
                pp = type ? p->yarn_stop[1][pp_sect - 1][yarn_ext - 1] : -p->yarn_stop[0][pp_sect - 1][yarn_ext - 1];
                realgsp[yarn_ext - 1] = gauze_pos[gn - 1] + pp + sp;
            }
            else
            {
                pp = type ? -p->yarn_stop[0][pp_sect - 1][yarn_ext - 1] : p->yarn_stop[1][pp_sect - 1][yarn_ext - 1];
                realgsp[yarn_ext - 1] = gauze_pos[gn - 1] + pp + sp;
            }
        }
    }

    if(p->ext_piece_num > 1)
    {
        return;
    }
    /* 续片纱嘴 */
    for(i = 0; i < 8; i++)
    {
        if(p->ext_piece_enable[i + 1])
        {
            uchar yarn_xp[GAUZE_NUM] = {0};
            int width = p->flower_width;
            int inter = p->ext_piece_inter;
            int yxp = 0;
            int yxp_ext = 0;

            int j = 0;
            for(j = 0; j < GAUZE_NUM; ++j)
            {
                uchar g = p->ext_piece_yarn[i + 1][j];
                if(g >= 11 && g <= 18)
                {
                    g -= 2;
                }
                yarn_xp[j] = g;
            }
            //memcpy(yarn_xp, p->ext_piece_yarn[i + 1], sizeof(yarn_xp));
            /* 窄纱嘴 */
            yxp = yarn_xp[yarn - 1];
            if (mrow % 2)
            {
                pp = type ? p->yarn_stop[1][pp_sect - 1][yxp - 1] : -p->yarn_stop[0][pp_sect - 1][yxp - 1];
                pp = gauze_pos[gn - 1] + pp + sp;
            }
            else
            {
                pp = type ? -p->yarn_stop[0][pp_sect - 1][yxp - 1] : p->yarn_stop[1][pp_sect - 1][yxp - 1];
                pp = gauze_pos[gn - 1] + pp + sp;
            }

            if(yxp > 0 && yxp < GAUZE_NUM + 1)
            {
                realgsp[yxp - 1] = pp + (width + inter) * (i + 1);
            }

            /* 宽纱嘴 */
            yxp_ext = yarn_xp[yarn_ext - 1];
            if (mrow % 2)
            {
                pp = type ? p->yarn_stop[1][pp_sect - 1][yxp_ext - 1] : -p->yarn_stop[0][pp_sect - 1][yxp_ext - 1];
                pp = gauze_pos[gn - 1] + pp + sp;
            }
            else
            {
                pp = type ? -p->yarn_stop[0][pp_sect - 1][yxp_ext - 1] : p->yarn_stop[1][pp_sect - 1][yxp_ext - 1];
                pp = gauze_pos[gn - 1] + pp + sp;
            }

            if(yxp_ext > 0 && yxp_ext < GAUZE_NUM + 1)
            {
                realgsp[yxp_ext - 1] = pp + (width + inter) * (i + 1);
            }
        }
    }
}
/*
 * [in]translator: translator instance
 * [in]jrow: 跳行行数
 * [out]realgsp: 真正的停放点
 * @note: 更新最后一次使用的纱嘴位置，带到针板外边，引塔夏纱嘴除外
 */
void translator_update_last_used_gauze_pos(MH_KNIT *p, int *gauze_pos, int jrow, int *realgsp)
{
    /* bit15-bit0: 纱嘴1-16号，置位表示已经更新过 */
    int updated = 0x0;
    int i = 0;
    int j = 0;
    int s = 0;
    int total_needle = p->total_needle;
    int sp = p->start_needle - p->left_bound;

    if (p->knit_page == NULL)
    {
        return;
    }

    for (i = jrow - 1; i >= 1; i--)
    {
        uchar *pcon = (uchar*)GetControlPage(p, i + 1);

        for (s = 0; s < 2; s++)
        {
            int yc = pcon[80 + s * 2] | (pcon[80 + s * 2 + 1] << 8);
            int io = pcon[82 + s * 3];

            if (yc == 0)
            {
                continue;
            }

            for (j = 0; j < GAUZE_NUM; j++)
            {
                int filter = 0x01 << (GAUZE_NUM - 1 - j);

                if ((yc & filter) == 0)
                {
                    continue;
                }
                /* 已处理过 */
                if (updated & filter)
                {
                    continue;
                }
                /* 对于引塔夏，不更改纱嘴位置 */
                if (pcon[121] == 0)
                {
                    if (i % 2)
                    {
                        gauze_pos[j] = total_needle - sp;
                    }
                    else
                    {
                        gauze_pos[j] = -sp;
                    }
                }

                updated |= filter;

                translator_get_real_parkpos(p, gauze_pos, i, realgsp, pcon, j + 1, io, TRUE);
            }
        }
    }
}
/* @translator: 转换器
 * @g: 纱嘴编号1-16
 * @pos: 纱嘴停放点
 * @can_update: 是否可以更新纱嘴位置
 * NOTE:如果更新了纱嘴位置，返回TRUE，否则返回FALSE
 */
int translator_update_parkpos (int *gauze_pos, int g, int pos, int can_update)
{
    if (g >= 1 && g <= 16)
    {
        if (can_update)
        {
            gauze_pos[g - 1] = pos;
            return TRUE;
        }
        else
        {
            if(gauze_pos[g - 1] == INVALID_GAUZE_POS)
            {
                gauze_pos[g - 1] = pos;
                return TRUE;
            }
        }
    }
    return FALSE;
}
/** \brief  :更新引塔夏纱嘴的位置
 *
 * \param   :[in]translator
 *           [in]pcon_buf-该行控制数据
 *           [in]mrow-machine row
 *           [in]start_pos-色码段的起点
 *           [in]end_pos-色码段的终点
 *           [out]realgsp-真正的纱嘴停放点
 *           [in]section-色码段个数
 *           [in]can_update-是否可以更新纱嘴位置
 * \return  :none
 * \date    :2014\08\20
 * \author  :herbert
 */
void translator_update_yinta_gauze_pos_con (MH_KNIT *p,
                                            int *yarn_pos,
                                            int mrow,
                                            uchar *pcon_buf,
                                            int *start_pos,
                                            int *end_pos,
                                            int *realgsp,
                                            int section,
                                            int can_update)
{
    int j;
    int s;
    int g;
    int g1_pos = pcon_buf[121] & 0x7F;
    int gauze_pos = 0;

    for (j = 0; j < section; j++)
    {
        if (mrow % 2)
        {
            /* 从左往右 */
            for (s = 0; s < 2; s++)
            {
                g = 0;
                /* 低４位，窄纱嘴 */
                if (s == 0)
                {
                    g = pcon_buf[5 + j * 10] & 0x0F;
                }
                else
                {
                    g = pcon_buf[9 + j * 10] & 0x0F;
                }

                /* 查１号纱嘴位置 */
                if (g == 0)
                {
                    if (g1_pos == j + 1)
                    {
                        g = 1;
                    }
                }
                gauze_pos = can_update ? end_pos[j] : start_pos[j];
                if (translator_update_parkpos (yarn_pos, g, gauze_pos, can_update))
                {
                    translator_get_real_parkpos (p, yarn_pos, mrow, realgsp, pcon_buf, g, 0, can_update);
                }

                g = 0;
                /* 高４位，宽纱嘴 */
                if (s == 0)
                {
                    g = (pcon_buf[5 + j * 10] & 0xF0) >> 4;
                }
                else
                {
                    g = (pcon_buf[9 + j * 10] & 0xF0) >> 4;
                }

                /* 查１号纱嘴位置 */
                if (g == 0)
                {
                    if (g1_pos == j + 1)
                    {
                        g = 1;
                    }
                }

                gauze_pos = can_update ? end_pos[j] : start_pos[j];
                if (translator_update_parkpos (yarn_pos, g, gauze_pos, can_update))
                {
                    translator_get_real_parkpos (p, yarn_pos, mrow, realgsp, pcon_buf, g, 0, can_update);
                }
            }

        }
        else
        {
            /* 从右往左 */
            for (s = 0; s < 2; s++)
            {
                g = 0;
                /* 低４位，窄纱嘴 */
                if (s == 0)
                {
                    g = pcon_buf[5 + j * 10] & 0x0F;
                }
                else
                {
                    g = pcon_buf[9 + j * 10] & 0x0F;
                }

                /* 查１号纱嘴位置 */
                if (g == 0)
                {
                    if (g1_pos == j + 1)
                    {
                        g = 1;
                    }
                }

                gauze_pos = can_update ? start_pos[j] : end_pos[j];
                if (translator_update_parkpos (yarn_pos, g, gauze_pos, can_update))
                {
                    translator_get_real_parkpos (p, yarn_pos, mrow, realgsp, pcon_buf, g, 0, can_update);
                }

                g = 0;
                /* 高４位，宽纱嘴 */
                if (s == 0)
                {
                    g = (pcon_buf[5 + j * 10] & 0xF0) >> 4;
                }
                else
                {
                    g = (pcon_buf[9 + j * 10] & 0xF0) >> 4;
                }

                /* 查１号纱嘴位置 */
                if (g == 0)
                {
                    if (g1_pos == j + 1)
                    {
                        g = 1;
                    }
                }

                gauze_pos = can_update ? start_pos[j] : end_pos[j];
                if (translator_update_parkpos (yarn_pos, g, gauze_pos, can_update))
                {
                    translator_get_real_parkpos (p, yarn_pos, mrow, realgsp, pcon_buf, g, 0, can_update);
                }
            }
        }
    }
}
/** \brief  :更新引塔夏纱嘴的位置，按照纱嘴位置来判断每个色码段使用的纱嘴
 *
 * \param   :[in]translator
 *           [in]pcon_buf-该行控制数据
 *           [in]mrow-machine row
 *           [in]start_pos-色码段的起点
 *           [in]end_pos-色码段的终点
 *           [out]realgsp-真正的纱嘴停放点
 *           [in]section-色码段个数
 *           [in]can_update-是否可以更新纱嘴位置
 * \return  :none
 * \date    :2014\12\31
 * \author  :herbert
 */
static void translator_update_yinta_gauze_pos_cnt (MH_KNIT *p,
                                                   int *yarn_pos,
                                                   int mrow,
                                                   uchar *pcon_buf,
                                                   int *start_pos,
                                                   int *end_pos,
                                                   int *realgsp,
                                                   int section,
                                                   int can_update)
{
    int i;
    int j;
    int s = 0;

    int gauze_pos = 0;
    int gauze[2] = { 0 };
    int sp = p->start_needle - p->left_bound;

    gauze[0] = pcon_buf[80] | (pcon_buf[81] << 8);
    gauze[1] = pcon_buf[83] | (pcon_buf[84] << 8);

    for (s = 0; s < 2; s++)
    {
        if (gauze[s] == 0)
        {
            continue;
        }

        for (i = 0; i < GAUZE_NUM; i++)
        {
            int filter = 0x01 << (GAUZE_NUM - 1 - i);
            if (gauze[s] & filter)
            {
                if (mrow % 2)
                {
                    for (j = 0; j < section; j++)
                    {
                        /* rightward */
                        if (yarn_pos[i] == INVALID_GAUZE_POS)
                        {
                            if (can_update)
                            {
                                gauze_pos = end_pos[j];
                            }
                            else
                            {
                                gauze_pos = -sp;
                            }
                        }
                        else if ((yarn_pos[i] <= end_pos[j]))
                        {
                            gauze_pos = can_update ? end_pos[j] : start_pos[j];
                        }
                        else
                        {
                            continue;
                        }

                        if (translator_update_parkpos (yarn_pos, i + 1, gauze_pos, can_update))
                        {
                            translator_get_real_parkpos (p, yarn_pos, mrow, realgsp, pcon_buf, i + 1, 0, can_update);
                        }
                        break;
                    }
                }
                else
                {
                    for (j = section - 1; j >= 0; j--)
                    {
                        /* leftward */
                        if (yarn_pos[i] == INVALID_GAUZE_POS)
                        {
                            if (can_update)
                            {
                                gauze_pos = start_pos[j];
                            }
                            else
                            {
                                gauze_pos = p->total_needle;
                            }
                        }
                        else if ((yarn_pos[i] >= start_pos[j]))
                        {
                            gauze_pos = can_update ? start_pos[j] : end_pos[j];
                        }
                        else
                        {
                            continue;
                        }

                        if (translator_update_parkpos (yarn_pos, i + 1, gauze_pos, can_update))
                        {
                            translator_get_real_parkpos (p, yarn_pos, mrow, realgsp, pcon_buf, i + 1, 0, can_update);
                        }
                        break;
                    }
                }
            }
        }
    }
}
/*
 * [in]translator: translator instance
 * [in]mrow: 机器行数
 * [in]pcon_buf:当前行控制缓冲区
 * [in]gauze: 当前执行的纱嘴
 * [in]pos: 纱嘴停放的位置
 * [in/out]realgsp: 真正的纱嘴停放点
 * [in]can_update:　是否能更新
 */
static void translator_update_gauze_pos_con (MH_KNIT *p,
                                             int *gauze_pos,
                                             int mrow,
                                             uchar *pcon_buf,
                                             int io,
                                             int gauze,
                                             int pos,
                                             int *realgsp,
                                             int can_update)
{
    int i = 0;
    int total_needle = p->total_needle;
    int left = p->st_board.yarn_left;
    int right = p->st_board.yarn_right;
    int filter = 0;

    for (i = 0; i < GAUZE_NUM; i++)
    {
        filter = 0x01 << (GAUZE_NUM - 1 - i);
        if (gauze & filter)
        {
            if (can_update)
            {
                /* 获取执行之后的纱嘴停放点 */
                if (io == 0x02)
                {
                    pos = (mrow % 2) ? total_needle + right : -left;
                }
            }
            else
            {
                /* 获取执行之前的纱嘴停放点 */
                if (gauze_pos[i] == INVALID_GAUZE_POS)
                {
                    if (io == 0x01)
                    {
                        pos = (mrow % 2) ? -left : (total_needle + right);
                    }
                }
            }

            if (translator_update_parkpos (gauze_pos, i + 1, pos, can_update))
            {
                translator_get_real_parkpos (p, gauze_pos, mrow, realgsp, pcon_buf, i + 1, io, can_update);
            }
        }
    }
}
/*
 * [in]translator: translator instance
 * [in]mrow: machine row, index form 1
 * [in] pcon_buf: con buffer
 * [in/out]realgsp: 真正的纱嘴停放点，包括纱嘴更换过之后的和续片对应的纱嘴
 * [in] can_update: can update gauze pos or not
 */
static void translator_update_con_gsp (MH_KNIT *p,
                                       int *gauze_pos,
                                       int mrow,
                                       uchar *pcon_buf,
                                       int *realgsp,
                                       int can_update)
{
    int s = 0;
    int i = 0;
    int gauze[2] = { 0 };
    int pcolor[4] = { 0 };
    int prow[4] = { 0 };
    int pos = 0;
    int start[GAUZE_NUM] = { 0 };
    int end[GAUZE_NUM] = { 0 };
    int section = 0;                //引塔夏色码段数

    for (i = 0; i < GAUZE_NUM; i++)
    {
        start[i] = -1;
        end[i] = -1;
    }

    //sys1
    gauze[0] = (pcon_buf[81] << 8) | pcon_buf[80];
    //sys2
    gauze[1] = (pcon_buf[84] << 8) | pcon_buf[83];
    //sys1, front
    pcolor[0] = pcon_buf[3] | (pcon_buf[4] << 8);
    pcolor[0] |= pcon_buf[7] | (pcon_buf[8] << 8);
    prow[0] = pcon_buf[0] | (pcon_buf[1] << 8);
    //sys1, back
    pcolor[1] = pcon_buf[13] | (pcon_buf[14] << 8);
    pcolor[1] |= pcon_buf[17] | (pcon_buf[18] << 8);
    prow[1] = pcon_buf[10] | (pcon_buf[11] << 8);
    //sys1, front
    pcolor[2] = pcon_buf[23] | (pcon_buf[24] << 8);
    pcolor[2] |= pcon_buf[27] | (pcon_buf[28] << 8);
    prow[2] = pcon_buf[20] | (pcon_buf[21] << 8);
    //sys1, back
    pcolor[3] = pcon_buf[33] | (pcon_buf[34] << 8);
    pcolor[3] |= pcon_buf[37] | (pcon_buf[38] << 8);
    prow[3] = pcon_buf[30] | (pcon_buf[31] << 8);

    for (s = 0; s < 2; s++)
    {
        if (gauze[s] == 0)
        {
            continue;
        }

        if (pcon_buf[121] & 0x80)           //引塔夏
        {
            section = translator_get_yinta_range (p->flower_data, p->flower_width, p->flower_height,
                    &prow[s * 2], start, end, NULL);
            if (section < 1)
            {
                continue;
            }
            translator_update_yinta_gauze_pos_cnt(p, gauze_pos, mrow, pcon_buf,
                start, end, realgsp, section, can_update);
        }
        else
        {
            int io = pcon_buf[82 + s * 3];
            pos = translator_get_dat_end (p->flower_data, p->flower_width, p->flower_height,
                    mrow, &prow[s * 2], &pcolor[s * 2], can_update);
            translator_update_gauze_pos_con (p, gauze_pos, mrow, pcon_buf, io, gauze[s],
                pos, realgsp, can_update);
        }
    }
}
/*
 * @translator: 转换器
 * @row: 机器行数，从０开始
 * @gsp[out]: 纱嘴停放点
 * NOTE: 获取执行到第row行的纱嘴停放位置
 */
int translator_get_gauze_pos(MH_KNIT *p, int row, int *gsp)
{
    int h = 0;
    int i = 0;

    if(!p->knit_page)
    {
        return -1;
    }

    int gauze_pos[GAUZE_NUM] = {0};
    /* init gauze pos to invalid pos */
    for (i = 0; i < GAUZE_NUM; i++)
    {
        gauze_pos[i] = INVALID_GAUZE_POS;
    }
#if 1
    int clip_enable = p->mac.clip_enable;
    if(clip_enable || p->board_enable)
    {
        int yarn = p->st_board.yarn;
        int mode = p->st_board.mode;
        if(yarn > 0 && yarn < GAUZE_NUM + 1 && mode > 0 && mode < 4)
        {
            gauze_pos[yarn - 1] = -GetYarnLeftOutStop(p) + p->yarn_stop[0][0][yarn - 1];
        }
    }
#endif
    /* 模拟执行从第一行到当前行的纱嘴停放位置 */
    for (h = 0; h < row; h++)
    {
        uchar *pcon_buf = (uchar*)&p->knit_page[h];

        translator_update_con_gsp(p, gauze_pos, h + 1, pcon_buf, gsp, TRUE);
    }
#if 0
    translator_update_last_used_gauze_pos(p, gauze_pos, row + 1, gsp);
#endif
    int end_line = p->total_line;
#if 0
    if(p->knit_state.fp_enable)
    {
        end_line = p->backpiece_start_line - 1;
    }
#endif
    /* 计算从当前行到最后一行纱嘴初始位置 */
    for (h = row; h < end_line; h++)
    {
        uchar *pcon_buf = (uchar*)&p->knit_page[h];

        translator_update_con_gsp(p, gauze_pos, h + 1, pcon_buf, gsp, FALSE);
    }

    return 0;
}
/*
 * [in]translator: translator instance
 * [in]mrow: machine row, index form 1
 * [in] pcon_buf: con buffer
 * [in] pcnt_buf: cnt buffer
 */
void translator_exec (TRANSLATOR *translator, int mrow, uchar *pcon_buf, uchar *pcnt_buf)
{
    assert (translator != NULL);
    assert (pcon_buf != NULL);
    assert (pcnt_buf != NULL);

    int s = 0;
    int i = 0;
    int j = 0;
    int gauze[2] = { 0 };
    int pcolor[4] = { 0 };
    int prow[4] = { 0 };
    int pos = 0;
    int start[GAUZE_NUM] = { 0 };
    int end[GAUZE_NUM] = { 0 };
    int section = 0;                //引塔夏色码段数
    int new_gauze[GAUZE_NUM] = { 0 };
    int out_gauze[2] = { 0 };
    int gauze_in = 0;

    for (i = 0; i < GAUZE_NUM; i++)
    {
        start[i] = -1;
        end[i] = -1;
    }
    //转换动作
    line_cnt2con (mrow, pcon_buf, pcnt_buf);

    //sys1
    gauze[0] = pcnt_buf[81];
    //sys2
    gauze[1] = pcnt_buf[84];
    //sys1, front
    pcolor[0] = pcnt_buf[3] | (pcnt_buf[4] << 8);
    pcolor[0] |= pcnt_buf[7] | (pcnt_buf[8] << 8);
    prow[0] = pcnt_buf[0] | (pcnt_buf[1] << 8);
    //sys1, back
    pcolor[1] = pcnt_buf[13] | (pcnt_buf[14] << 8);
    pcolor[1] |= pcnt_buf[17] | (pcnt_buf[18] << 8);
    prow[1] = pcnt_buf[10] | (pcnt_buf[11] << 8);
    //sys1, front
    pcolor[2] = pcnt_buf[23] | (pcnt_buf[24] << 8);
    pcolor[2] |= pcnt_buf[27] | (pcnt_buf[28] << 8);
    prow[2] = pcnt_buf[20] | (pcnt_buf[21] << 8);
    //sys1, back
    pcolor[3] = pcnt_buf[33] | (pcnt_buf[34] << 8);
    pcolor[3] |= pcnt_buf[37] | (pcnt_buf[38] << 8);
    prow[3] = pcnt_buf[30] | (pcnt_buf[31] << 8);

    gauze_in = pcnt_buf[39];

    for (s = 0; s < 2; s++)
    {
        int tmp;
        if (gauze[s] == 0)
        {
            continue;
        }

        if (pcnt_buf[113] & 0x7F)           //引塔夏
        {
            section = translator_get_yinta_range (translator->pat_buf, translator->width, translator->height,
                    &prow[s * 2], start, end, NULL);
            if (section < 1)
            {
                continue;
            }
            translator_update_yinta_gauze_pos (translator, mrow, gauze[s], gauze_in, new_gauze,
                start, end, section);


            /**< 写纱嘴 */
            for (j = 0; j < GAUZE_NUM; j++)
            {
                if (new_gauze[j] == 0)
                {
                    break;
                }
                out_gauze[s] |= 0x01 << (GAUZE_NUM - 1 - (new_gauze[j] - 1));

                uchar low = new_gauze[j] & 0x00FF;
                uchar high = (new_gauze[j] & 0xFF00) >> 8;


                if (low == 1)           /**< 1号纱嘴 */
                {
                    pcon_buf[121] = 0x80 | (s * 8 + (j + 1));

                }
                else if (low > 1)                    /**< 其他纱嘴 */
                {
                    pcon_buf[5 + s * 4 + j * 10] = low - 1;
                }

                if (high == 1)          /**< 1号纱嘴 */
                {
                    pcon_buf[121] = 0x80 | (s * 8 + (j + 1));
                }
                else if (high > 1)                    /**< 其他纱嘴 */
                {
                    pcon_buf[5 + s * 4 + j * 10] &= 0x0F;
                    pcon_buf[5 + s * 4 + j * 10] |= (high - 1) << 4;
                }
            }
        }
        else
        {
            pos = translator_get_dat_end (translator->pat_buf, translator->width, translator->height,
                    mrow, &prow[s * 2], &pcolor[s * 2], TRUE);
            if (pos >= 0)
            {
                tmp = translator_update_gauze_pos (translator, mrow, gauze[s], pos);
                out_gauze[s] = translator_reverse (tmp);
            }
        }
    }

    pcon_buf[80] = out_gauze[0] & 0x00FF;
    pcon_buf[81] = (out_gauze[0] & 0xFF00) >> 8;

    pcon_buf[83] = out_gauze[1] & 0x00FF;
    pcon_buf[84] = (out_gauze[1] & 0xFF00) >> 8;

    /**< 设置纱嘴带入带出标志 */
    for(i = 0; i < 16; i++)
    {
        if(out_gauze[0] & (0x01 << (15 - i)))
        {
            if(translator->io[i] == YARN_OUT)
            {
                translator->io[i] = YARN_IN;
                pcon_buf[82] = FLAG_YARN_IN;
            }
        }

        if(out_gauze[1] & (0x01 << (15 - i)))
        {
            if(translator->io[i] == YARN_OUT)
            {
                translator->io[i] = YARN_IN;
                pcon_buf[85] = FLAG_YARN_IN;
            }
        }
    }
}
/*
 *
 */
void translator_iterate_loop (TRANSLATOR *translator, uchar *des)
{
    assert (translator != NULL);
    assert (des != NULL);

    if (translator->prm_buf == NULL)
    {
        return;
    }

    int i = 0;
    uchar *data = translator->prm_buf;
    for(i = 0; i < 64; i++)
    {
        int start = (data[(i << 3) + 1] << 8) | data[(i << 3)];
        int end = (data[(i << 3) + 3] << 8) | data[(i << 3) + 2];
        int num = (data[(i << 3) + 5] << 8) | data[(i << 3) + 4];
        if(start > 0 && end > 0 && num > 0)
        {
            des[(end << 7) + 122] = start & 0xFF;
            des[(end << 7) + 123] = (start >> 8) & 0xFF;
            des[(end << 7) + 124] = end & 0xFF;
            des[(end << 7) + 125] = (end >> 8) & 0xFF;
            des[(end << 7) + 126] = num & 0xFF;
            des[(end << 7) + 127] = (num >> 8) & 0xFF;
        }
    }
}
/*
 *
 */
int translator_save_cntfile (TRANSLATOR *translator)
{
    assert (translator != NULL);
    assert (translator->cnt_fn != NULL);

    FILE *fp = fopen(translator->cnt_fn, "r+");
    long int size = 0;
    int height = 0;
    int h = 0;
    uchar *src = NULL;
    uchar *des = NULL;

    if (fp == NULL)
    {
        return 1;
    }

    fseek(fp, 0L, SEEK_END);
    size = ftell(fp);
    src = (uchar*)malloc(size);
    des = (uchar*)malloc(size);
    memset(des, 0, size);
    fseek(fp, 0L, SEEK_SET);
    fread(src, 1, size, fp);
    height = (size / sizeof(KNIT_PAGE)) - 1;


    for(h = 0; h < height; h++)
    {
        uchar *pcon_buf = des + (h + 1) * sizeof(KNIT_PAGE);
        uchar *pcnt_buf = src + (h + 1) * sizeof(KNIT_PAGE);

        translator_exec (translator, h + 1, pcon_buf, pcnt_buf);
    }

    translator_iterate_loop (translator, des);

    fseek(fp, 0L, SEEK_SET);
    des[4] = 0xAA;
    des[128 + 98] = 0xAA;
    fwrite(des, 1, size, fp);
    fclose(fp);
    free(src);
    free(des);
    MH_FILE_SYNC();
    return 0;
}
/*
 *
 */
int translator_save_patfile (TRANSLATOR *translator)
{
    assert (translator != NULL);
    FILE *fp = NULL;
    int width = translator->width;
    int height = translator->height;
    uchar *buf = NULL;
    uchar *pat_buf = translator->pat_buf;
    int span = (width + 1) / 2;
    int size = span * height;
    int i = 0;
    int j = 0;

    fp = fopen (translator->pat_fn, "w");

    if (fp == NULL)
    {
        return 1;
    }

    buf = (uchar*)malloc (size);
    memset ((void*)buf, 0, size);

    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            uchar c = pat_buf[i * width + j];
            if ((j % 2) == 0)
            {
                buf[i * span + j / 2] |= c << 4;
            }
            else
            {
                buf[i * span + j / 2] |= c;
            }
        }
    }

    fwrite (&width, 1, 2, fp);
    fwrite (&height, 1, 2, fp);

    fseek (fp, 16, SEEK_SET);
    fwrite (buf, 1, size, fp);

    fclose (fp);

    FREE (buf);
    MH_FILE_SYNC();

    return 0;
}
/*
 * @translator: 转换器
 * @pat_fn:花样文件名
 * @type:0-pat, 1-dat
 * @ret:TRUE-成功，FALSE-失败
 */
int translator_read_patfile (TRANSLATOR *translator, const char *pat_fn, int type)
{
    assert (translator != NULL);
    assert (pat_fn != NULL);

    printf ("pat_fn = %s\n", pat_fn);
    /**< 读取花样 */
    int width = 0;
    int height = 0;
    int fp = open(pat_fn, O_RDONLY);
    if(fp < 0)
    {
        return FALSE;
    }

    if(read(fp, &width, 2) != 2)
    {
        close(fp);
        return FALSE;
    }

    if(read(fp, &height, 2) != 2)
    {
        close(fp);
        return FALSE;
    }

    if((width <= 0) || (height <= 0))
    {
        close(fp);
        return FALSE;
    }

    int span = (width + 1) / 2;
    int size = span * height;

    if (type == 1)      //dat
    {
        lseek (fp, 16, SEEK_SET);
    }
    else
    {
        lseek(fp, span, SEEK_SET);
    }

    uchar *pData = (uchar*)malloc(size);
    int nRead = read(fp, pData, size);
    close(fp);
    if(nRead != size)
    {
        FREE(pData);
        return FALSE;
    }

    strcpy (translator->pat_fn, pat_fn);
    translator->width = width;
    translator->height = height;
    translator->pat_buf = (uchar*)malloc (width * height);

    int h, w;
    for(h = 0; h < height; h++)
    {
        for(w = 0; w < width; w++)
        {
            uchar c = pData[span * h + w / 2];
            c = w & 1 ? c & 0xF : c >> 4;
            translator->pat_buf[h * width + w] = c;
        }
    }
    FREE(pData);

    return TRUE;
}
/*
 *
 */
void* mh_read_file (const char *path, int size)
{
    void *buf = NULL;
    int file = open (path, O_RDONLY);
    if (file < 0)
    {
        return buf;
    }
    buf = malloc (size);
    memset (buf, 0, size);
    read (file, buf, size);
    close (file);
    return buf;
}
/*
 *
 */
int translator_init (TRANSLATOR *translator,
                     const char *cnt_fn,
                     const char *pat_fn,
                     const char *prm_fn,
                     int type)
{
    assert (translator != NULL);


    int i = 0;

    if (cnt_fn != NULL)
    {
        strcpy (translator->cnt_fn, cnt_fn);
    }

    if (pat_fn != NULL)
    {
        if (!translator_read_patfile (translator, pat_fn, type))
        {
            return FALSE;
        }
    }

    if (prm_fn != NULL)
    {
        translator->prm_buf = mh_read_file (prm_fn, 512);
    }

    /**< 初始化纱嘴停放点和方向 */
    for (i = 0; i < GAUZE_NUM; i++)
    {
        translator->io[i] = 2;
        translator->gauze_pos[i] = -1;
        translator->gauze_dir[i] = -1;
    }
    printf ("translator init end\n");
    return TRUE;
}
/*
 * NOTE:cnt_fn, prm_fn can be null
 * type:0-pat,1-dat
 */
TRANSLATOR* translator_new (const char *cnt_fn, const char *pat_fn, const char *prm_fn, int type)
{
    TRANSLATOR *translator = (TRANSLATOR*)malloc (sizeof (TRANSLATOR));
    memset (translator, 0, sizeof (TRANSLATOR));

    if (!translator_init (translator, cnt_fn, pat_fn, prm_fn, type))
    {
        free (translator);
        translator = NULL;
        return NULL;
    }

    return translator;
}
/*
 * @translator: 翻译器
 * @stitch: 线圈位置buf
 * @pcon_buf: 控制缓冲区
 * @sys: 0-3代表系统１到系统４
 * @back: 0-前床；１-后床
 * @pos: 线圈位置
 * NOTE:设置某个系统前床或者后床的线圈位置
 */
void translator_set_sys_stitch (TRANSLATOR *translator,
                                int *stitch,
                                uchar *pcon_buf,
                                int sys,
                                int back,
                                int pos)
{
    assert (translator != NULL);
    assert (stitch != NULL);
    assert (pcon_buf != NULL);

    int pat_width = translator->width;
    uchar *pdat_buf = translator->pat_buf;
    int pat_row;
    int c;
    int act;
    int codeA, codeH;
    int gauze;

    pat_row = pcon_buf[sys * 20 + back * 10] | (pcon_buf[sys * 20 + back * 10 + 1] << 8);
    act = pcon_buf[sys * 20 + back * 10 + 2];
    codeA = pcon_buf[sys * 20 + back * 10 + 3] | (pcon_buf[sys * 20 + back * 10 + 4] << 8);
    codeA &= 0x7FFF;
    codeH = pcon_buf[sys * 20 + back * 10 + 7] | (pcon_buf[sys * 20 + back * 10 + 8] << 8);
    codeH &= 0x7FFF;
    gauze = pcon_buf[81 + sys * 3] | (pcon_buf[81 + sys * 3] << 8);

    if (pat_row > 0 && pat_row <= translator->height)
    {
        c = *(pdat_buf + (pat_row - 1) * pat_width + pos);
        /* A位 */
        if (codeA & (0x01 << c))
        {
            /* 编织 */
            if (IS_KNIT(act) && gauze)
            {
                stitch[pos] = 1;
            }
            else
            {
                stitch[pos] = 0;
            }
        }
        /* H位 */
        if (codeH & (0x01 << c))
        {
            /* 编织 */
            if (IS_KNIT(act) && gauze)
            {
                stitch[pos] = 1;
            }
            else if (IS_RECV(act))
            {
                int num = pcon_buf[101] & 0x0F;
                int dir = pcon_buf[100];

                if (sys >= 2)
                {
                    num = pcon_buf[117] & 0x0F;
                    dir = pcon_buf[113];
                }
                if ((dir & 0xC0) == 0x80)
                {
                    /* 右摇 */
                    if (back)
                    {
                        /* 后床接针，前翻后 */
                        if (pos + num < pat_width)
                        {
                            stitch[pos + num] = 1;
                        }
                    }
                    else
                    {
                        /* 前床接针，后翻前 */
                        if (pos - num >= 0)
                        {
                            stitch[pos - num] = 1;
                        }
                    }
                }
                else
                {
                    /* 左摇 */
                    if (back)
                    {
                        /* 后床接针，前翻后 */
                        if (pos - num >= 0)
                        {
                            stitch[pos - num] = 1;
                        }
                    }
                    else
                    {
                        /* 前床接针，后翻前 */
                        if (pos + num < pat_width)
                        {
                            stitch[pos + num] = 1;
                        }
                    }
                }
            }
        }
    }
}

/*
 * @translator:翻译器　
 * @fstitch: 前板线圈
 * @bstitch: 后板线圈
 * @pcon_buf: 控制缓冲区
 */
void translator_set_stitch (TRANSLATOR *translator,
                            int *fstitch,
                            int *bstitch,
                            uchar *pcon_buf)
{
    assert (translator != NULL);
    assert (fstitch != NULL);
    assert (bstitch != NULL);
    assert (pcon_buf != NULL);

    int i = 0;

    for (i = 0; i < translator->width; i++)
    {
        int s = 0;
        for (s = 0; s < 4; s++)
        {
            /* 前床 */
            translator_set_sys_stitch (translator,
                                   fstitch,
                                   pcon_buf,
                                   s,
                                   0,
                                   i);
            /* 后床 */
            translator_set_sys_stitch (translator,
                                   bstitch,
                                   pcon_buf,
                                   s,
                                   1,
                                   i);
        }
    }
}
/*
 *
 */
void translator_free (TRANSLATOR *translator)
{
    assert (translator != NULL);

    FREE (translator->pat_buf);
    FREE (translator->prm_buf);
}
